Runnable documents =================== The publisher takes a script and produces a document. This is the other direction: **the Markdown document is the source file**, with MATLAB living in fenced code blocks, and it runs directly. .. code-block:: none ## Setting up ```matlab m = dsge_model('nk'); m = solve(m); ``` The prose is never executed and never has to be commented out, which is the whole point of writing it this way round. .. code-block:: matlab rise.mdrun("round.md") % run the code blocks rise.publish("round.md") % run it and typeset it rise.m2md("walkthrough.m") % script -> document rise.md2m("walkthrough.md") % document -> script .. contents:: :local: :depth: 2 What runs, and what does not ----------------------------- Only fenced blocks run, and only those whose language is one RISE recognizes. A fence tagged ``noexec`` is shown to the reader and never executed, which is how a slow, interactive or deliberately broken example stays in the document: .. code-block:: none ```matlab noexec estimate(m, data) % takes an hour; shown, not run ``` ``Sections`` narrows the run, matching either a fence tag or the nearest heading above the block: .. code-block:: matlab rise.mdrun("round.md", Sections="Setting up") Where the code runs -------------------- This is the option that matters for anything automated. .. list-table:: :header-rows: 1 :widths: 22 78 * - ``Workspace`` - Meaning * - ``"caller"`` - the default; the code runs in your workspace, as if you had typed it * - ``"fresh"`` - a workspace of its own, leaving yours untouched * - a struct - a workspace of its own, seeded with those variables A fresh or seeded run **hands its workspace back**: .. code-block:: matlab w = rise.mdrun("round.md", Workspace="fresh"); w.peak % what the document computed Without that a documentation build could execute a page but not look at what the page produced, which is most of the reason to run it. The returned struct carries only what the document assigned. A seeded run is what makes a long document testable in pieces: run one section, then run the next starting from what the first produced. .. code-block:: matlab setup = rise.mdrun("round.md", Workspace="fresh", Sections="Setting up"); calc = rise.mdrun("round.md", Workspace=setup, Sections="The calculation"); Anything that is neither of the two names nor a struct is refused by ``RISE:mdrun:badWorkspace``. ``Echo`` prints each block before running it and is off by default, so an automated build is not buried in the code it is running. ``DryRun`` returns the assembled code without running any of it. The round trip --------------- A script and a document are two ways of writing the same material, and the conversion between them is a **fixed point**: convert, convert back, and convert again, and the second document equals the first. .. code-block:: matlab md = rise.m2md("walkthrough.m"); back = rise.md2m(md); again = rise.m2md(back); % identical to md That property is what lets a team keep both forms without watching them drift. It holds by construction rather than by agreement between two functions: whitespace is normalized in the one place both converters pass through, so a run of blank lines collapses to one, trailing space goes, and the ends are trimmed. Everything the publisher's grammar carries survives the trip: headings and their depth, **a heading's label**, prose with its emphasis and lists, display mathematics, and the code. A label dropped in conversion would be a cross-reference that silently stops resolving, so it is carried and tested. Neither converter overwrites an existing file. Pass ``Overwrite=true`` to say you meant it, or ``SaveAs`` to choose the destination. One pipeline, two front ends ----------------------------- ``rise.publish`` accepts either form. The script lexer and the Markdown lexer produce the same typed block list, and everything after that is shared: execution, output capture, figure export and the LaTeX backend. So a document and the script it converts to give the same PDF, and a new output format is written once rather than twice. Worked example: ``rise-modern-tutorials/Reporting/runnable_documents``. .. seealso:: :doc:`Publishing a script`, :doc:`Report documents`